package com.topcent.tioxyc.controller;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.topcent.tioxyc.constants.KeyConstant;
import com.topcent.tioxyc.pojo.cc.NineZeroDayStagnationTableCC;
import com.topcent.tioxyc.pojo.cc.OneDayStagnationTableCC;
import com.topcent.tioxyc.pojo.cc.OriginalStagnantTableCC;
import com.topcent.tioxyc.util.ApiClient;
import com.topcent.tioxyc.util.ConnmeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Header;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: 陈百万
 * @date: 2025/10/21 18:24
 * @Description: 呆滞物料项目
 */
@Slf4j
@RestController
public class StagnationMaterialController {

    @GetMapping("stagnationLogicalProcessing")
    public String stagnationLogicalProcessing() {
        Header[] headers = ConnmeUtils.createHeaders();

        // 获取三种表单数据
        // 原呆滞表更新表
        List<OriginalStagnantTableCC> originalList = fetchJianDaoYunData(
                headers, "67f8aa2676b9b3942c49035f", "68f7241d345992cce893c2c7", OriginalStagnantTableCC.class
        );

        // 低周转或停滞物料（1天）
        List<OneDayStagnationTableCC> oneDayList = fetchJianDaoYunData(
                headers, "67f8aa2676b9b3942c49035f", "68f73d15ab7e76af5f188fce", OneDayStagnationTableCC.class
        );

        // 低周转或停滞物料（90天）
        List<NineZeroDayStagnationTableCC> nineZeroList = fetchJianDaoYunData(
                headers, "67f8aa2676b9b3942c49035f", "68f73d9ea8c263fa7affe82c", NineZeroDayStagnationTableCC.class
        );

        // 预处理原表：构建各种匹配条件的映射表（键为匹配字符串，值为原表记录）
        // 映射1：销售订单+批次（格式："销售订单_批次"，空值按实际值处理）
        Map<String, OriginalStagnantTableCC> soBatchMap = originalList.stream()
                .collect(Collectors.toMap(
                        original -> buildKey(original.get_widget_1761027101433(), original.get_widget_1761027101451()),
                        original -> original,
                        (v1, v2) -> v1 // 重复键保留第一条
                ));

        // 映射2：批次单独（键为批次号）
        Map<String, OriginalStagnantTableCC> batchMap = originalList.stream()
                .collect(Collectors.toMap(
                        OriginalStagnantTableCC::get_widget_1761027101451, // 批次号
                        original -> original,
                        (v1, v2) -> v1
                ));

        // 映射3：销售订单+物料（格式："销售订单_物料"）
        Map<String, OriginalStagnantTableCC> soMaterialMap = originalList.stream()
                .collect(Collectors.toMap(
                        original -> buildKey(original.get_widget_1761027101433(), original.get_widget_1761027101436()),
                        original -> original,
                        (v1, v2) -> v1
                ));

        // 映射4：物料单独（键为物料，用于PA开头的物料匹配）
        Map<String, OriginalStagnantTableCC> materialMap = originalList.stream()
                .filter(original -> {
                    String material = original.get_widget_1761027101436();
                    return material != null && material.startsWith("PA"); // 只保留PA开头的物料
                })
                .collect(Collectors.toMap(
                        OriginalStagnantTableCC::get_widget_1761027101436, // 物料
                        original -> original,
                        (v1, v2) -> v1
                ));
        // 3. 用90天表数据分步骤匹配更新原表
        // 3.1 第一步：90天表的“销售订单+批次”匹配原表的“销售订单+批次”
        Set<String> matchedIds = new HashSet<>(); // 记录已匹配的原表ID，避免重复处理
        List<NineZeroDayStagnationTableCC> nineZeroUnmatchedStep1 = new ArrayList<>(); // 第一步未匹配的90天记录

        for (NineZeroDayStagnationTableCC nineZero : nineZeroList) {
            String nineZeroSo = nineZero.get_widget_1761033630635(); // 90天表销售订单
            String nineZeroBatch = nineZero.get_widget_1761033630636(); // 90天表批次
            String key = buildKey(nineZeroSo, nineZeroBatch); // 构建匹配键

            OriginalStagnantTableCC original = soBatchMap.get(key);
            if (original != null) {
                // 匹配成功：更新字段
                updateOriginalTable(original, nineZero, matchedIds);
            } else {
                // 未匹配：加入下一步处理
                nineZeroUnmatchedStep1.add(nineZero);
            }
        }

        // 3.2 第二步：第一步未匹配的90天记录，用“批次单独”匹配
        List<NineZeroDayStagnationTableCC> nineZeroUnmatchedStep2 = new ArrayList<>();
        for (NineZeroDayStagnationTableCC nineZero : nineZeroUnmatchedStep1) {
            String nineZeroBatch = nineZero.get_widget_1761033630636(); // 90天表批次
            OriginalStagnantTableCC original = batchMap.get(nineZeroBatch);

            if (original != null && !matchedIds.contains(original.get_id())) { // 排除已匹配的
                updateOriginalTable(original, nineZero, matchedIds);
            } else {
                nineZeroUnmatchedStep2.add(nineZero);
            }
        }

        // 3.3 第三步：第二步未匹配的90天记录，用“销售订单+物料”匹配
        List<NineZeroDayStagnationTableCC> nineZeroUnmatchedStep3 = new ArrayList<>();
        for (NineZeroDayStagnationTableCC nineZero : nineZeroUnmatchedStep2) {
            String nineZeroSo = nineZero.get_widget_1761033630635(); // 90天表销售订单
            String nineZeroMaterial = nineZero.get_widget_1761033630614(); // 90天表物料
            String key = buildKey(nineZeroSo, nineZeroMaterial);

            OriginalStagnantTableCC original = soMaterialMap.get(key);
            if (original != null && !matchedIds.contains(original.get_id())) {
                updateOriginalTable(original, nineZero, matchedIds);
            } else {
                nineZeroUnmatchedStep3.add(nineZero);
            }
        }

        // 3.4 第四步：第三步未匹配的，用PA开头物料匹配90天表的物料
        for (NineZeroDayStagnationTableCC nineZero : nineZeroUnmatchedStep3) {
            String nineZeroMaterial = nineZero.get_widget_1761033630614(); // 90天表物料
            OriginalStagnantTableCC original = materialMap.get(nineZeroMaterial);

            if (original != null && !matchedIds.contains(original.get_id())) {
                updateOriginalTable(original, nineZero, matchedIds);
            }
        }

        // 4. 用1天表数据匹配剩余未匹配的原表记录（只走前两步）
        // 4.1 第一步：1天表的“销售订单+批次”匹配
        List<OneDayStagnationTableCC> oneDayUnmatchedStep1 = new ArrayList<>();
        for (OneDayStagnationTableCC oneDay : oneDayList) {
            String oneDaySo = oneDay.get_widget_1761033493622(); // 1天表销售订单
            String oneDayBatch = oneDay.get_widget_1761033493623(); // 1天表批次
            String key = buildKey(oneDaySo, oneDayBatch);

            OriginalStagnantTableCC original = soBatchMap.get(key);
            if (original != null && !matchedIds.contains(original.get_id())) {
                updateOriginalTableWithOneDay(original, oneDay, matchedIds);
            } else {
                oneDayUnmatchedStep1.add(oneDay);
            }
        }

        // 4.2 第二步：1天表未匹配的，用“批次单独”匹配
        for (OneDayStagnationTableCC oneDay : oneDayUnmatchedStep1) {
            String oneDayBatch = oneDay.get_widget_1761033493623(); // 1天表批次
            OriginalStagnantTableCC original = batchMap.get(oneDayBatch);

            if (original != null && !matchedIds.contains(original.get_id())) {
                updateOriginalTableWithOneDay(original, oneDay, matchedIds);
            }
        }

        // 2. 新增逻辑：处理90天表的呆滞新增情况
        // 2.1 过滤90天表数据（按三个条件）
        List<NineZeroDayStagnationTableCC> filteredNineZeroList = nineZeroList.stream()
                .filter(nineZero -> {
                    // 条件1：物料（_widget_1761033630614）不以PA开头（去掉PA开头的）
                    String material = nineZero.get_widget_1761033630614();
                    if (material != null && material.startsWith("PA")) {
                        return false; // 过滤掉
                    }

                    // 条件2：无消耗天数（_widget_1761033630633）>90天（去掉<=90的）
                    Double noConsumptionDays = nineZero.get_widget_1761033630633();
                    if (noConsumptionDays != null && noConsumptionDays <= 90) {
                        return false; // 过滤掉
                    }

                    // 条件3：产品组（_widget_1761033630623）不等于“1.MD”（去掉等于的）
                    String productGroup = nineZero.get_widget_1761033630623();
                    if ("1.MD".equals(productGroup)) {
                        return false; // 过滤掉
                    }

                    // 保留符合条件的记录
                    return true;
                }).toList();

        // 2.2 提取原呆滞表中已有的批次（用于判断是否需要新增）
        Set<String> originalBatches = originalList.stream()
                .map(OriginalStagnantTableCC::get_widget_1761027101451) // 原表批次字段
                .collect(Collectors.toSet());

        // 2.3 遍历过滤后的90天表记录，批次不在原表中则新增到原表
        for (NineZeroDayStagnationTableCC nineZero : filteredNineZeroList) {
            String nineZeroBatch = nineZero.get_widget_1761033630636(); // 90天表批次

            // 若原表中没有该批次，新增记录
            if (!originalBatches.contains(nineZeroBatch)) {
                OriginalStagnantTableCC newRecord = new OriginalStagnantTableCC();

                // 赋值字段（按对应关系映射）
                newRecord.set_widget_1761027101433(nineZero.get_widget_1761033630635()); // 销售订单
                newRecord.set_widget_1761027101436(nineZero.get_widget_1761033630614()); // 物料（最新）
                newRecord.set_widget_1761027101451(nineZeroBatch); // 批次
                newRecord.set_widget_1761037504382(nineZero.get_widget_1761033630625()); // SAP库存数量
                newRecord.set_widget_1761037504383(nineZero.get_widget_1761033630627()); // SAP库存价值

                // 其他字段赋默认值（根据业务需求，如差值、是否匹配等）
                newRecord.set_widget_1761101694605("新增"); // 标记为新增（非匹配）
                // 库存最新数量/价值若没有则为null，差值自动计算（后续步骤会处理）

                // 添加到原表列表
                originalList.add(newRecord);
                // 更新原表批次集合（避免重复新增）
                originalBatches.add(nineZeroBatch);
            }
        }

        List<Map<String, Object>> resultList = new ArrayList<>();
        // 5. 标记未匹配的记录为“否”
        for (OriginalStagnantTableCC original : originalList) {
            if (!matchedIds.contains(original.get_id()) && StringUtils.isBlank(original.get_widget_1761101694605())) {
                original.set_widget_1761101694605("否");
            }
            original.set_id(null);
            resultList.add(ConnmeUtils.convertEntityToMap(original));
        }

        // 6. 插入简道云（复用之前的插入逻辑）先删 后插
        //批量删除简道云数据
        ConnmeUtils.selectAndDeleteList(headers, "67f8aa2676b9b3942c49035f", "68f7241d345992cce893c2c7", "");
        //批量新增到简道云
        ConnmeUtils.batchAddList(headers, "67f8aa2676b9b3942c49035f", "68f7241d345992cce893c2c7",  resultList);
        return "呆滞数据更新：" + resultList.size();
    }

    /**
     * 用90天表数据更新原表字段
     */
    private void updateOriginalTable(OriginalStagnantTableCC original, NineZeroDayStagnationTableCC nineZero, Set<String> matchedIds) {
        // 1. 赋值SAP库存数量和价值
        original.set_widget_1761037504382(nineZero.get_widget_1761033630625()); // SAP库存数量
        original.set_widget_1761037504383(nineZero.get_widget_1761033630627()); // SAP库存价值

        // 2. 计算差值（SAP字段 - 库存最新字段，处理null为0）
        double stockQty = original.get_widget_1761027101438() != null ? original.get_widget_1761027101438() : 0;
        double sapQty = nineZero.get_widget_1761033630625() != null ? nineZero.get_widget_1761033630625() : 0;
        original.set_widget_1761101694603(sapQty - stockQty); // 库存数量差值

        BigDecimal stockValue = original.get_widget_1761027101439() != null ? original.get_widget_1761027101439() : BigDecimal.ZERO;
        BigDecimal sapValue = nineZero.get_widget_1761033630627() != null ? nineZero.get_widget_1761033630627() : BigDecimal.ZERO;
        original.set_widget_1761101694604(sapValue.subtract(stockValue)); // 库存价值差值

        // 3. 标记匹配成功
        original.set_widget_1761101694605("是");
        matchedIds.add(original.get_id()); // 记录已匹配
    }

    /**
     * 用1天表数据更新原表字段（逻辑同90天表）
     */
    private void updateOriginalTableWithOneDay(OriginalStagnantTableCC original, OneDayStagnationTableCC oneDay, Set<String> matchedIds) {
        // 1. 赋值SAP库存数量和价值
        original.set_widget_1761037504382(oneDay.get_widget_1761033493612()); // SAP库存数量
        original.set_widget_1761037504383(oneDay.get_widget_1761033493614()); // SAP库存价值

        // 2. 计算差值
        double stockQty = original.get_widget_1761027101438() != null ? original.get_widget_1761027101438() : 0;
        double sapQty = oneDay.get_widget_1761033493612() != null ? oneDay.get_widget_1761033493612() : 0;
        original.set_widget_1761101694603(sapQty - stockQty);

        BigDecimal stockValue = original.get_widget_1761027101439() != null ? original.get_widget_1761027101439() : BigDecimal.ZERO;
        BigDecimal sapValue = oneDay.get_widget_1761033493614() != null ? oneDay.get_widget_1761033493614() : BigDecimal.ZERO;
        original.set_widget_1761101694604(sapValue.subtract(stockValue));

        // 3. 标记匹配成功
        original.set_widget_1761101694605("是");
        matchedIds.add(original.get_id());
    }



    /**
     * 通用方法：从简道云分页获取表单数据
     * @param headers 请求头
     * @param appId 应用ID
     * @param entryId 表单ID
     * @param clazz 实体类Class（用于JSON转换）
     * @return 转换后的实体类列表
     * @param <T> 泛型：适配不同实体类（SalesDataAnalysis/ZPurchaseOrderList等）
     */
    private <T> List<T> fetchJianDaoYunData(Header[] headers, String appId, String entryId, Class<T> clazz) {
        List<T> resultList = new ArrayList<>();
        Map<String, Object> params = new HashMap<>();
        params.put("app_id", appId);
        params.put("entry_id", entryId);
        boolean hasMore = true;
        String lastDataId = ""; // 分页标记：上一页最后一条数据的ID

        do {
            // 设置分页参数（首次请求无data_id，后续请求携带上一页最后一条ID）
            if (!lastDataId.isEmpty()) {
                params.put("data_id", lastDataId);
            }
            params.put("limit", 100); // 每页100条

            // 调用简道云API
            String jsonParams = JSONUtil.toJsonStr(params);
            JSONObject response = ApiClient.sendPostRequest(
                    KeyConstant.Jian_URL + "/v5/app/entry/data/list",
                    headers,
                    jsonParams
            );

            // 解析数据并转换为实体类
            String dataJson = response.getStr("data");
            JSONArray dataArray = JSONUtil.parseArray(dataJson);
            List<T> pageData = JSONUtil.toList(dataArray, clazz);

            // 更新分页状态（是否还有下一页）
            if (pageData.size() == 100) {
                // 取当前页最后一条数据的ID，作为下一页的查询起点
                // 假设实体类有get_id()方法（简道云数据通常有_id字段）
                T lastData = pageData.get(pageData.size() - 1);
                lastDataId = getLastDataId(lastData); // 反射获取_id字段值
            } else {
                hasMore = false; // 不足100条，无下一页
            }

            // 累加数据
            resultList.addAll(pageData);
            System.out.println("数组大小："+ resultList.size());
        } while (hasMore);

        return resultList;
    }

    /**
     * 反射获取实体类的_id字段值（简道云数据默认有_id作为唯一标识）
     */
    private <T> String getLastDataId(T data) {
        try {
            // 假设实体类有get_id()方法
            Method method = data.getClass().getMethod("get_id");
            return (String) method.invoke(data);
        } catch (Exception e) {
            // 异常处理：若没有_id字段，返回空（终止分页）
            return "";
        }
    }

    /**
     * 构建匹配键（处理空值，直接拼接，空值按实际值保留）
     * 例：销售订单为"SO123"，批次为"B001" → 键为"SO123_B001"；销售订单为null，批次为"B001" → 键为"null_B001"
     */
    private String buildKey(String part1, String part2) {
        return part1 + "_" + part2;
    }
}
